package cn.cleanarch.infra.idp.pms.service.impl;

import cn.cleanarch.infra.idp.commons.domain.dto.PageResult;
import cn.cleanarch.infra.idp.commons.utils.Times;
import cn.cleanarch.infra.idp.pms.dao.repository.ProjectCategoryRepository;
import cn.cleanarch.infra.idp.pms.domain.dto.ProjectCategoryDTO;
import cn.cleanarch.infra.idp.pms.domain.entity.ProjectCategory;
import cn.cleanarch.infra.idp.pms.domain.query.ProjectCategoryQuery;
import cn.cleanarch.infra.idp.pms.service.ProjectCategoryService;
import cn.cleanarch.infra.idp.uaa.core.util.LoginSessionTool;
import cn.cleanarch.infra.idp.web.exception.Exceptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目分类服务实现类
 */
@Service
public class ProjectCategoryServiceImpl implements ProjectCategoryService {

    private final ProjectCategoryRepository projectCategoryRepository;

    public ProjectCategoryServiceImpl(ProjectCategoryRepository projectCategoryRepository) {
        this.projectCategoryRepository = projectCategoryRepository;
    }

    @Override
    public PageResult<ProjectCategoryDTO> pageQuery(ProjectCategoryQuery query) {
        // 使用自定义的分页查询方法
        Page<ProjectCategory> page = projectCategoryRepository.pageQuery(query);
        
        // 手动转换ProjectCategory实体到ProjectCategoryDTO
        List<ProjectCategoryDTO> dtoList = page.getRecords().stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
        
        return new PageResult<ProjectCategoryDTO>((int)page.getTotal(), dtoList);
    }

    @Override
    public List<ProjectCategoryDTO> listAll() {
        QueryWrapper<ProjectCategory> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("sort_order");
        
        List<ProjectCategory> categories = projectCategoryRepository.list(wrapper);
        
        return categories.stream()
            .map(this::convertToDTO)
            .collect(Collectors.toList());
    }

    @Override
    public ProjectCategory getById(Long id) {
        if (id == null) {
            return null;
        }
        return projectCategoryRepository.getById(id);
    }

    @Override
    @Transactional
    public ProjectCategoryDTO create(ProjectCategoryDTO dto) {
        ProjectCategory category = new ProjectCategory();
        category.setName(dto.getName());
        category.setDescription(dto.getDescription());
        category.setParentId(dto.getParentId());
        category.setSortOrder(dto.getSortOrder() != null ? dto.getSortOrder() : 0);
        
        LocalDateTime now = LocalDateTime.now();
        category.setCreateTime(now);
        category.setUpdateTime(now);
        category.setCreateBy(LoginSessionTool.getCurrentUser().getUserId());
        category.setUpdateBy(LoginSessionTool.getCurrentUser().getUserId());

        projectCategoryRepository.save(category);
        
        return convertToDTO(category);
    }

    @Override
    @Transactional
    public ProjectCategoryDTO update(ProjectCategoryDTO dto) {
        ProjectCategory existing = projectCategoryRepository.getById(dto.getId());
        if (existing == null) {
            Exceptions.throwException("项目分类不存在");
        }

        existing.setName(dto.getName());
        existing.setDescription(dto.getDescription());
        existing.setParentId(dto.getParentId());
        existing.setSortOrder(dto.getSortOrder());
        existing.setUpdateTime(LocalDateTime.now());
        existing.setUpdateBy(LoginSessionTool.getCurrentUser().getUserId());
        
        projectCategoryRepository.updateById(existing);
        
        return convertToDTO(existing);
    }

    @Override
    @Transactional
    public Boolean delete(Long id) {
        if (id == null) {
            return false;
        }
        
        ProjectCategory category = projectCategoryRepository.getById(id);
        if (category == null) {
            return false;
        }
        
        // 检查是否有子分类
        QueryWrapper<ProjectCategory> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", id);
        List<ProjectCategory> children = projectCategoryRepository.list(wrapper);
        if (!children.isEmpty()) {
            Exceptions.throwException("该分类下存在子分类，无法删除");
        }
        
        projectCategoryRepository.removeById(id);
        
        return true;
    }

    /**
     * 将ProjectCategory实体转换为ProjectCategoryDTO
     */
    private ProjectCategoryDTO convertToDTO(ProjectCategory category) {
        ProjectCategoryDTO dto = new ProjectCategoryDTO();
        dto.setId(category.getId());
        dto.setName(category.getName());
        dto.setDescription(category.getDescription());
        dto.setParentId(category.getParentId());
        dto.setSortOrder(category.getSortOrder());
        // 直接赋值LocalDateTime类型
        dto.setCreateTime(category.getCreateTime());
        dto.setUpdateTime(category.getUpdateTime());
        dto.setCreateBy(category.getCreateBy());
        dto.setUpdateBy(category.getUpdateBy());
        
        // 查询父分类名称
        if (category.getParentId() != null) {
            ProjectCategory parent = projectCategoryRepository.getById(category.getParentId());
            if (parent != null) {
                dto.setParentName(parent.getName());
            }
        }
        
        return dto;
    }
}